昨天有提到在查詢 Enum 時,看了官方文件以及其他文章後,發現對 Enum 少了滿多基本的認識,之前使用都是覺得很方便而已ㄝ並不知道一些底層運作或是 edge case 會怎麼跑
而既然鐵人賽的標題是叫做學習日記,那就趁這次來把多學到的知識整理下來吧
先來講講昨天節錄官方文件的最後一句話
TypeScript provides both numeric and string-based enums.
TypeScript 有提供
數字枚舉
以及字串枚舉
什麼是數字枚舉呢?
數字枚舉
如以下範例:
enum Direction {
Up,
Down,
Left,
Right
}
因為沒有賦值,TypeScript 會自動把第一個枚舉值預設為 0,之後就遞增 +1 +1
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Righ // 3
}
等價於下面寫法
enum Direction {
Up = 0,
Down = 1,
Left = 2,
Right = 3
}
編譯成 JavaScript,可以看到兩邊的值相同
自動遞增的這種行為, 他的好處是可以讓我們更專注在同組 Enum 中每個值是不同的這一件事,而不用花費心力去設定預設值
另外,如果數字枚舉的數字是從中間開始,那後面的值也會由該值為起點遞增
直接看範例
enum Direction {
East,
West,
South,
North,
Northeast = 0,
Northwest,
Southeast,
Southwest,
}
這樣寫的話,從 East
開始就沒有賦予初始值,依照前面所說的自動預設值, East
會預設為 0
,但 Northeast
我們有賦予值 0
,所以 TypeScript 會從 Northeast
再重新遞增
enum Direction {
East, // 0
West, // 1
South, // 2
North, // 3
Northeast = 0, // 0 <== 重新開始遞增
Northwest, // 1
Southeast, // 2
Southwest, // 3
}
不過這樣寫就會出現一些問題,像是這樣判斷的時候就會看起來怪怪的
console.log(Direction.East === Direction.Northeast); // true
語意上看起來怪怪的,反而失去了我們使用 Enum 的初衷,增加可讀性
字串枚舉中沒有自動遞增的行為,且一定要手動預設值
好處是可以更進一步的增加可閱讀性
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
可以注意的是 數字枚舉
以及 字串枚舉
編譯成 JavaScript 時的表現不太相同
Heterogeneous enums
就是兩個摻在一起,有字串枚舉也有數字枚舉,技術上是做的得到,但是目前本身也沒有碰過使用到的情境,一般選一種使用就很夠了
官方文件 heterogeneous-enums 也有提到
Unless you’re really trying to take advantage of JavaScript’s runtime behavior in a clever way, it’s advised that you don’t do this.
除非你真的想用 巧妙的方式 利用 JavaScript 運行的行為而使用異構枚舉,不然不建議這樣做(是奪巧妙
enum Heterogeneous {
Success = "SUCCESS",
Fail = 0
}
常數枚舉在編譯時會被簡化成 JavaScript 中的普通物件,不會生成額外的程式碼
間單來說這樣使用編譯出來的 JavaScript 就不會有這個枚舉類型了
const enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
但是在執行上,跟前面的範例使用起來都差不多
還是會正常的運作
主要的優點是可以簡化編譯後的輸出,因為編譯後 const Enum 不會在 JavaScript 中出現,所以可以提升專案效能、減輕專案重量
無敵官網 Enums
其他人的鐵人賽 枚舉 / 列舉 (Enum) by 威爾豬